package com.springboot.demo.common.utils;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

/**
 * @ClassName:RegularCheckUtils.java
 * @Package com.utils
 * @Description:正则表达式工具类
 * @Author JuoChiu
 * @Date  2017年10月31日下午2:52:33
 * @Version
 */
@SuppressWarnings("all") // 去除警告信息 
public class RegularCheckUtils {
	
    /**
     * @MethodName:isPhoneLegal
     * @Author JuoChiu
     * @Date 2017年10月26日 下午5:12:14
     * @Description:通用：大陆号码或香港号码均可
     * @param str
     * @return
     * @throws PatternSyntaxException
     * @ReturnType boolean
     */
    public static boolean isPhoneLegal(String str){  
        return isChinaPhoneLegal(str) || isHKPhoneLegal(str);  
    }
    
    /**
     * @MethodName:isChinaPhoneLegal
     * @Author JuoChiu
     * @Date 2017年10月26日 下午5:12:42
     * @Description:国内手机号码11位数，匹配格式：前三位固定格式+后8位任意数 
     * 此方法中前三位格式有： 
     * 13+任意数 
     * 15+除4的任意数 
     * 18+除1和4的任意数 
     * 17+除9的任意数 
     * 147}
     * @param str
     * @return
     * @throws PatternSyntaxException
     * @ReturnType boolean
     */
    public static boolean isChinaPhoneLegal(String str){  
        String regExp = "^((13[0-9])|(15[^4])|(18[0,2,3,5-9])|(17[0-8])|(147))\\d{8}$";
        Pattern p = Pattern.compile(regExp);  
        Matcher m = p.matcher(str);  
        return m.matches();  
    }
  
    /**
     * @MethodName:isHKPhoneLegal
     * @Author JuoChiu
     * @Date 2017年10月26日 下午5:13:19
     * @Description:香港手机号码8位数，5|6|8|9开头+7位任意数
     * @param str
     * @return
     * @throws PatternSyntaxException
     * @ReturnType boolean
     */
    public static boolean isHKPhoneLegal(String str){
        String regExp = "^(5|6|8|9)\\d{7}$";  
        Pattern p = Pattern.compile(regExp);  
        Matcher m = p.matcher(str);  
        return m.matches();  
    }
    
    /**
     * @MethodName:isTelePhone
     * @Author JuoChiu
     * @Date 2017年10月31日 下午2:10:09
     * @Description:固定电话号码验证
     * @param str
     * @return
     * @throws PatternSyntaxException
     * @ReturnType boolean
     */
    public static boolean isTelePhone(String str){
        Pattern p1 = null;
        Pattern p2 = null;
        Matcher m = null;
        boolean result = false;  
        p1 = Pattern.compile("^[0][1-9]{2,3}-[0-9]{5,10}$");  // 验证带区号的
        p2 = Pattern.compile("^[1-9]{1}[0-9]{5,8}$");         // 验证没有区号的
        if(str.length() > 9)
        {   m = p1.matcher(str);
        	result = m.matches();  
        }else{
            m = p2.matcher(str);
            result = m.matches(); 
        }  
        return result;
    }
    
    /**
     * @MethodName:isPostCode
     * @Author JuoChiu
     * @Date 2017年10月31日 下午2:18:24
     * @Description:匹配中国邮政编码
     * @param str
     * @return
     * @throws PatternSyntaxException
     * @ReturnType boolean
     */
    public static boolean isPostCode(String str){
        String regExp = "[1-9]\\d{5}";  
        Pattern p = Pattern.compile(regExp);  
        Matcher m = p.matcher(str);  
        return m.matches();
    }
    
    /**
     * @MethodName:isEmail
     * @Author JuoChiu
     * @Date 2017年10月31日 下午2:25:21
     * @Description:验证邮箱
     * @param str
     * @return
     * @throws PatternSyntaxException
     * @ReturnType boolean
     */
    public static boolean isEmail(String str){
    	String regExp = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
    	Pattern p = Pattern.compile(regExp);
    	Matcher m = p.matcher(str);
        return m.matches();
    }
    
    /**
     * @MethodName:isIPAddress
     * @Author JuoChiu
     * @Date 2017年10月31日 下午2:30:57
     * @Description:iPv4的ip地址（1~255）.（0~255）.（0~255）.（0~255）的格式
     * @param str
     * @return
     * @throws PatternSyntaxException
     * @ReturnType boolean
     */
    public static boolean isIPAddress(String str){
    	String regExp = "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."  
                +"(00?\\d|1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."  
                +"(00?\\d|1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."  
                +"(00?\\d|1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$"; 
    	Pattern p = Pattern.compile(regExp);
    	Matcher m = p.matcher(str);
    	return m.matches();
    }
    
    /**
     * @MethodName:isUpChar
     * @Author JuoChiu
     * @Date 2017年10月31日 下午2:36:55
     * @Description:验证大写字母
     * @param str
     * @return
     * @ReturnType boolean
     */
    public static boolean isUpChar(String str){
    	String regExp = "^[A-Z]+$";
    	Pattern p = Pattern.compile(regExp);
    	Matcher m = p.matcher(str);
    	return m.matches();
    }
    
    /**
     * @MethodName:isLowChar
     * @Author JuoChiu
     * @Date 2017年10月31日 下午2:38:17
     * @Description:验证小写字母
     * @param str
     * @return
     * @ReturnType boolean
     */
    public static boolean isLowChar(String str){
    	String regExp = "^[a-z]+$";
    	Pattern p = Pattern.compile(regExp);
    	Matcher m = p.matcher(str);
    	return m.matches();
    }
    
    /**
     * @MethodName:isLetter
     * @Author JuoChiu
     * @Date 2017年10月31日 下午2:39:27
     * @Description:验证输入字母
     * @param str
     * @return
     * @ReturnType boolean
     */
    public static boolean isLetter(String str){
    	String regExp = "^[A-Za-z]+$";
    	Pattern p = Pattern.compile(regExp);
    	Matcher m = p.matcher(str);
    	return m.matches();
    }
    
    /**
     * @MethodName:isChinese
     * @Author JuoChiu
     * @Date 2017年10月31日 下午2:40:20
     * @Description:验证输入汉字
     * @param str
     * @return
     * @ReturnType boolean
     */
    public static boolean isChinese(String str){
    	String regExp = "^[\u4e00-\u9fa5],{0,}$";
    	Pattern p = Pattern.compile(regExp);
    	Matcher m = p.matcher(str);
    	return m.matches();
    }
    
    /**
     * @MethodName:isUserName
     * @Author JuoChiu
     * @Date 2017年11月22日 上午11:19:38
     * @Description:验证用户昵称（用户名）
     * @param str
     * @return
     * @ReturnType boolean
     */
    public static boolean isUserName(String str){
    	// 中英文（长度至少一位）
    	String regExp = "^[\u4e00-\u9fa5,A-Za-z]{1,}$";
    	Pattern p = Pattern.compile(regExp);
    	Matcher m = p.matcher(str);
    	return m.matches();
    }
    
    /**
     * @MethodName:isInternetURL
     * @Author JuoChiu
     * @Date 2017年10月31日 下午2:45:29
     * @Description:验证网址Url
     * @param str
     * @return
     * @throws PatternSyntaxException
     * @ReturnType boolean
     */
    public static boolean isInternetURL(String str){
    	String regExp = "^http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w- ./?%&=]*)?$";
    	Pattern p = Pattern.compile(regExp);
    	Matcher m = p.matcher(str);
    	return m.matches();
    }
    
    /**
     * @MethodName:isCarLicense
     * @Author JuoChiu
     * @Date 2017年10月27日 上午8:59:47
     * @Description:验证车牌号
     * @param str
     * @return
     * @throws PatternSyntaxException
     * @ReturnType boolean
     */
    public static boolean isCarLicense(String str){
    	 /**
    	  * 车牌号格式验证
    	  * "^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-Z0-9]{4}[A-Z0-9挂学警港澳]{1}$"
    	  * 
    	  * ^[\u4e00-\u9fa5]{1}代表以汉字开头并且只有一个，这个汉字是车辆所在省的简称
    	  * [A-Z]{1}代表A-Z的大写英文字母且只有一个，代表该车所在地的地市一级代码
    	  * [A-Z0-9]{4}代表后面四个数字是字母和数字的组合
    	  * [A-Z0-9挂学警港澳]{1}代表最后一个由字母数字或者特殊字组成
    	  * */  
        String regExp = "^[\u4e00-\u9fa5]{1}[A-Z]{1}[A-Z0-9]{4}[A-Z0-9挂学警港澳]{1}$";  
        Pattern p = Pattern.compile(regExp);  
        Matcher m = p.matcher(str);
        return m.matches();
    }
    
    /**
     * @MethodName:isPassWord
     * @Author JuoChiu
     * @Date 2017年11月22日 上午10:49:31
     * @Description:验证密码：只能6位以上的英文或数字
     * @param str
     * @return
     * @ReturnType boolean
     */
    public static boolean isPassWord(String str){
    	String regExp = "^[A-Za-z0-9]{6,}$";
    	Pattern p = Pattern.compile(regExp);  
        Matcher m = p.matcher(str);
        return m.matches();
    }
    
    /**
     * @MethodName:
     * @Author JuoChiu
     * @Date 2017年11月3日 上午10:02:25
     * @Description:计算最后一位身份证验证码
     * @param str：身份证前十七位数
     * @return
     * @ReturnType char
     */
    public char getValidateCode(String str){   
    	int[] weight={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2}; //十七位数字本体码权重   
    	char[] validate={ '1','0','X','9','8','7','6','5','4','3','2'}; //mod11,对应校验码字符值       
        int sum=0;   
        int mode=0;   
        for(int i=0;i<str.length();i++){   
            sum=sum+Integer.parseInt(String.valueOf(str.charAt(i)))*weight[i];   
        }   
        mode=sum%11;   
        return validate[mode];   
    }
    
    /**
     * @MethodName:isIdCardNumber
     * @Author JuoChiu
     * @Date 2017年10月31日 下午2:01:32
     * @Description:18位身份证校验
     * @param idCard
     * @return
     * @ReturnType boolean
     */
    public static boolean isIdCardNumber(String idCard){
        Pattern pattern1 = Pattern.compile("^(\\d{6})(19|20)(\\d{2})(1[0-2]|0[1-9])(0[1-9]|[1-2][0-9]|3[0-1])(\\d{3})(\\d|X|x)?$");
        Matcher matcher = pattern1.matcher(idCard);
        int[] prefix = new int[]{7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
        int[] suffix = new int[]{ 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2 };
        if(matcher.matches()){
            Map<String, Object> cityMap = initCityMap();
            if(cityMap.get(idCard.substring(0,2)) == null ){
                return false;
            }
            int idCardWiSum=0; //用来保存前17位各自乖以加权因子后的总和  
            for(int i=0;i<17;i++){
                idCardWiSum+=Integer.valueOf(idCard.substring(i,i+1))*prefix[i];
            }
              
            int idCardMod=idCardWiSum%11;//计算出校验码所在数组的位置  
            String idCardLast=idCard.substring(17);//得到最后一位身份证号码  
              
            //如果等于2，则说明校验码是10，身份证号码最后一位应该是X
            if(idCardMod==2){
                if(idCardLast.equalsIgnoreCase("x")){
                    return true;
                }else{
                    return false;
                }
            }else{
                //用计算出的验证码与最后一位身份证号码匹配，如果一致，说明通过，否则是无效的身份证号码  
                if(idCardLast.equals(suffix[idCardMod]+"")){
                    return true;
                }else{  
                    return false;
                }  
           }  
        }  
        return false;  
    }
    /**
     * @MethodName:initCityMap
     * @Author JuoChiu
     * @Date 2017年10月31日 下午2:05:34
     * @Description:身份证开头前两位数字代表的省份
     * @return
     * @ReturnType Map<String,String>
     */
    private static Map<String, Object> initCityMap(){
        Map<String, Object> cityMap = new HashMap<>();
        cityMap.put("11", "北京");
        cityMap.put("12", "天津");
        cityMap.put("13", "河北");
        cityMap.put("14", "山西");
        cityMap.put("15", "内蒙古");
          
        cityMap.put("21", "辽宁");
        cityMap.put("22", "吉林");
        cityMap.put("23", "黑龙江");
          
        cityMap.put("31", "上海");
        cityMap.put("32", "江苏");
        cityMap.put("33", "浙江");
        cityMap.put("34", "安徽");
        cityMap.put("35", "福建");
        cityMap.put("36", "江西");
        cityMap.put("37", "山东");
          
        cityMap.put("41", "河南");
        cityMap.put("42", "湖北");
        cityMap.put("43", "湖南");
        cityMap.put("44", "广东");
        cityMap.put("45", "广西");
        cityMap.put("46", "海南");
          
        cityMap.put("50", "重庆");
        cityMap.put("51", "四川");
        cityMap.put("52", "贵州");
        cityMap.put("53", "云南");
        cityMap.put("54", "西藏");
          
        cityMap.put("61", "陕西");
        cityMap.put("62", "甘肃");
        cityMap.put("63", "青海");
        cityMap.put("64", "宁夏");
        cityMap.put("65", "新疆");
          
        /*cityMap.put("71", "台湾");
        cityMap.put("81", "香港");
        cityMap.put("82", "澳门");
        cityMap.put("91", "国外");
        System.out.println(cityMap.keySet().size());*/
        return cityMap;  
    }
    
    /**
     * @MethodName:isVersion
     * @Author JuoChiu
     * @Date 2017年12月22日 上午9:32:21
     * @Description:验证版本号
     * @param str
     * @return \\d+(\\.\\d+){0,2}  [0-9]+\\.[0-9]+\\.[0-9]
     * @ReturnType boolean
     */
    public static boolean isVersion(String str){
    	String regExp = "^\\d+(\\.\\d+){0,2}$";
    	Pattern p = Pattern.compile(regExp);  
        Matcher m = p.matcher(str);
        return m.matches();
    }
    
    /**
     * @MethodName:main
     * @Author JuoChiu
     * @Date 2017年10月26日 下午5:13:51
     * @Description:main方法测试
     * @param args
     * @ReturnType void
     */
    public static void main(String[] args) {
    	/*boolean strPhone = isPhoneLegal("12087223047");
    	System.out.println("---phone---> "+strPhone);
    	boolean strLicense = isCarLicense("渝A88888");
    	System.out.println("---license---> "+strLicense);
    	boolean strPostCard = isPostCode("471400");
    	System.out.println("---strPostCard---> "+strPostCard);
    	boolean strIdCard = isIdCardNumber("511324199602182593");
    	System.out.println("---strIdCard---> "+strIdCard);
    	boolean strPwd = isPassWord("sdfdsS");
    	System.out.println("----strPwd---》"+strPwd);*/
    	boolean strUserName = isUserName("你好qweqqqqqqq");
    	System.out.println("----strUserName---》"+strUserName);
	}
}
